let kind = KindTarget;
if pkg.get_manifest().get_build().len() == 0 {
- return Ok((Fresh, proc() Ok(()), proc() Ok(())))
+ return Ok((Fresh, proc(_) Ok(()), proc(_) Ok(())))
}
let (old, new) = dirs(cx, pkg, kind);
let old_loc = old.join("build");
let (_, new1) = dirs(cx, pkg, kind);
let new2 = new1.clone();
- let work1 = proc() { try!(fs::mkdir(&new1, USER_RWX)); Ok(()) };
- let work2 = proc() { try!(fs::mkdir(&new2, USER_RWX)); Ok(()) };
+ let work1 = proc(_) { try!(fs::mkdir(&new1, USER_RWX)); Ok(()) };
+ let work2 = proc(_) { try!(fs::mkdir(&new2, USER_RWX)); Ok(()) };
(work1, work2)
}
/// instances to actually perform the necessary work.
fn prepare(is_fresh: bool, loc: Path, fingerprint: String,
to_copy: Vec<(Path, Path)>) -> Preparation {
- let write_fingerprint = proc() {
+ let write_fingerprint = proc(desc_tx) {
+ drop(desc_tx);
try!(File::create(&loc).write_str(fingerprint.as_slice()));
Ok(())
};
- let move_old = proc() {
+ let move_old = proc(desc_tx) {
+ drop(desc_tx);
for &(ref src, ref dst) in to_copy.iter() {
try!(fs::rename(src, dst));
}
-use std::io::IoResult;
-
-use core::MultiShell;
use util::{CargoResult, Fresh, Dirty, Freshness};
-pub struct Job { dirty: Work, fresh: Work, desc: String }
+pub struct Job { dirty: Work, fresh: Work }
-pub type Work = proc():Send -> CargoResult<()>;
+/// Each proc should send its description before starting.
+/// It should send either once or close immediatly.
+pub type Work = proc(Sender<String>):Send -> CargoResult<()>;
impl Job {
/// Create a new job representing a unit of work.
- pub fn new(dirty: proc():Send -> CargoResult<()>,
- fresh: proc():Send -> CargoResult<()>,
- desc: String) -> Job {
- Job { dirty: dirty, fresh: fresh, desc: desc }
+ pub fn new(dirty: Work,
+ fresh: Work) -> Job {
+ Job { dirty: dirty, fresh: fresh }
}
/// Create a new job which will run `fresh` if the job is fresh and
///
/// Retains the same signature as `new` for compatibility. This job does not
/// describe itself to the console.
- pub fn noop(_dirty: proc():Send -> CargoResult<()>,
- fresh: proc():Send -> CargoResult<()>,
- _desc: String) -> Job {
- Job { dirty: proc() Ok(()), fresh: fresh, desc: String::new() }
+ pub fn noop(_dirty: Work,
+ fresh: Work) -> Job {
+ Job { dirty: proc(_) Ok(()), fresh: fresh }
}
/// Consumes this job by running it, returning the result of the
/// computation.
- pub fn run(self, fresh: Freshness) -> CargoResult<()> {
+ pub fn run(self, fresh: Freshness, sender: Sender<String>) -> CargoResult<()> {
match fresh {
- Fresh => (self.fresh)(),
- Dirty => (self.dirty)(),
- }
- }
-
- pub fn describe(&self, shell: &mut MultiShell) -> IoResult<()> {
- if self.desc.len() > 0 {
- try!(shell.status("Running", self.desc.as_slice()));
+ Fresh => (self.fresh)(sender),
+ Dirty => (self.dirty)(sender),
}
- Ok(())
}
}
// Prepare the fingerprint directory as the first step of building a package
let (target1, target2) = fingerprint::prepare_init(cx, pkg, KindTarget);
- let mut init = vec![(Job::new(target1, target2, String::new()), Fresh)];
+ let mut init = vec![(Job::new(target1, target2), Fresh)];
if cx.config.target().is_some() {
let (plugin1, plugin2) = fingerprint::prepare_init(cx, pkg, KindForHost);
- init.push((Job::new(plugin1, plugin2, String::new()), Fresh));
+ init.push((Job::new(plugin1, plugin2), Fresh));
}
jobs.enqueue(pkg, jq::StageStart, init);
Vec::new(), Vec::new());
for &target in targets.iter() {
let work = if target.get_profile().is_doc() {
- let (rustdoc, desc) = try!(rustdoc(pkg, target, cx));
- vec![(rustdoc, KindTarget, desc)]
+ let rustdoc = try!(rustdoc(pkg, target, cx));
+ vec![(rustdoc, KindTarget)]
} else {
let req = cx.get_requirement(pkg, target);
let mut rustc = try!(rustc(pkg, target, cx, req));
if target.get_profile().is_custom_build() {
- for &(ref mut work, _, _) in rustc.iter_mut() {
+ for &(ref mut work, _) in rustc.iter_mut() {
use std::mem;
let (old_build, script_output) = {
// 1 - create the output directory
// 2 - call rustc
// 3 - execute the command
- let rustc_cmd = mem::replace(work, proc() Ok(()));
- let replacement = proc() {
+ let rustc_cmd = mem::replace(work, proc(_) Ok(()));
+ let replacement = proc(desc_tx: Sender<String>) {
try!(create_directory());
- try!(rustc_cmd());
- execute_cmd()
+ try!(rustc_cmd(desc_tx.clone()));
+ execute_cmd(desc_tx)
};
mem::replace(work, replacement);
}
(false, false, _) if target.get_profile().get_env() == "test" => &mut tests,
(false, false, _) => &mut bins,
};
- for (work, kind, desc) in work.into_iter() {
+ for (work, kind) in work.into_iter() {
let (freshness, dirty, fresh) =
try!(fingerprint::prepare_target(cx, pkg, target, kind));
- let dirty = proc() { try!(work()); dirty() };
- dst.push((job(dirty, fresh, desc), freshness));
+ let dirty = proc(desc_tx: Sender<String>) {
+ try!(work(desc_tx.clone()));
+ dirty(desc_tx)
+ };
+ dst.push((job(dirty, fresh), freshness));
}
}
1 => pkg.get_manifest().get_build()[0].to_string(),
_ => format!("custom build commands"),
};
- let dirty = proc() {
- for cmd in build_cmds.into_iter() { try!(cmd()) }
- dirty()
+ let dirty = proc(desc_tx: Sender<String>) {
+ desc_tx.send_opt(desc).ok();
+ for cmd in build_cmds.into_iter() { try!(cmd(desc_tx.clone())) }
+ dirty(desc_tx)
};
- jobs.enqueue(pkg, jq::StageCustomBuild, vec![(job(dirty, fresh, desc),
+ jobs.enqueue(pkg, jq::StageCustomBuild, vec![(job(dirty, fresh),
freshness)]);
}
}
let pkg = pkg.to_string();
- Ok(proc() {
+ Ok(proc(desc_tx: Sender<String>) {
+ desc_tx.send_opt(p.to_string()).ok();
if first {
try!(if old_output.exists() {
fs::rename(&old_output, &output)
// Building command
let pkg = pkg.to_string();
- let work = proc() {
+ let work = proc(desc_tx: Sender<String>) {
+ desc_tx.send_opt(build_output.display().to_string()).ok();
+
if !build_output.exists() {
try!(fs::mkdir(&build_output, USER_RWX)
.chain_error(|| {
fn rustc(package: &Package, target: &Target,
cx: &mut Context, req: PlatformRequirement)
- -> CargoResult<Vec<(Work, Kind, String)> >{
+ -> CargoResult<Vec<(Work, Kind)> >{
let crate_types = target.rustc_crate_types();
let rustcs = try!(prepare_rustc(package, target, crate_types, cx, req));
Ok(rustcs.into_iter().map(|(rustc, kind)| {
let name = package.get_name().to_string();
- let desc = rustc.to_string();
let is_path_source = package.get_package_id().get_source_id().is_path();
let show_warnings = package.get_package_id() == cx.resolve.root() ||
is_path_source;
build_cmd_layout.build(pkg).join("output")
}).collect::<Vec<_>>();
- (proc() {
+ (proc(desc_tx: Sender<String>) {
let mut rustc = rustc;
let mut additional_library_paths = Vec::new();
rustc = rustc.arg("-l").arg(lib);
}
+ desc_tx.send_opt(rustc.to_string()).ok();
try!(rustc.exec().chain_error(|| {
human(format!("Could not compile `{}`.", name))
}));
Ok(())
- }, kind, desc)
+ }, kind)
}).collect())
}
fn rustdoc(package: &Package, target: &Target,
- cx: &mut Context) -> CargoResult<(Work, String)> {
+ cx: &mut Context) -> CargoResult<Work> {
let kind = KindTarget;
let pkg_root = package.get_root();
let cx_root = cx.layout(package, kind).proxy().dest().join("doc");
let primary = package.get_package_id() == cx.resolve.root();
let name = package.get_name().to_string();
let desc = rustdoc.to_string();
- Ok((proc() {
+ Ok(proc(desc_tx: Sender<String>) {
+ desc_tx.send(desc);
if primary {
try!(rustdoc.exec().chain_error(|| {
human(format!("Could not document `{}`.", name))
}))
}
Ok(())
- }, desc))
+ })
}
fn build_base_args(cx: &Context,